/* * (C) Copyright 2015-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Contributors: * ohun@live.cn (夜色) */ package com.mpush.test.client; import com.mpush.api.service.BaseService; import com.mpush.api.service.Listener; import com.mpush.api.spi.common.CacheManagerFactory; import com.mpush.api.spi.common.ServiceDiscoveryFactory; import com.mpush.api.srd.ServiceNames; import com.mpush.api.srd.ServiceNode; import com.mpush.cache.redis.manager.RedisManager; import com.mpush.client.connect.ClientConfig; import com.mpush.client.connect.ConnClientChannelHandler; import com.mpush.netty.codec.PacketDecoder; import com.mpush.netty.codec.PacketEncoder; import io.netty.bootstrap.Bootstrap; import io.netty.buffer.PooledByteBufAllocator; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.net.InetSocketAddress; import java.util.List; import static com.mpush.client.connect.ConnClientChannelHandler.CONFIG_KEY; public final class ConnClientBoot extends BaseService { private static final Logger LOGGER = LoggerFactory.getLogger(ConnClientBoot.class); private Bootstrap bootstrap; private NioEventLoopGroup workerGroup; @Override protected void doStart(Listener listener) throws Throwable { ServiceDiscoveryFactory.create().syncStart(); CacheManagerFactory.create().init(); this.workerGroup = new NioEventLoopGroup(); this.bootstrap = new Bootstrap(); bootstrap.group(workerGroup)// .option(ChannelOption.TCP_NODELAY, true)// .option(ChannelOption.SO_REUSEADDR, true)// .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)// .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 60 * 1000) .option(ChannelOption.SO_RCVBUF, 5 * 1024 * 1024) .channel(NioSocketChannel.class); bootstrap.handler(new ChannelInitializer<SocketChannel>() { // (4) @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast("decoder", new PacketDecoder()); ch.pipeline().addLast("encoder", PacketEncoder.INSTANCE); ch.pipeline().addLast("handler", new ConnClientChannelHandler()); } }); listener.onSuccess(); } @Override protected void doStop(Listener listener) throws Throwable { if (workerGroup != null) workerGroup.shutdownGracefully(); ServiceDiscoveryFactory.create().syncStop(); RedisManager.I.destroy(); listener.onSuccess(); } public List<ServiceNode> getServers() { return ServiceDiscoveryFactory.create().lookup(ServiceNames.CONN_SERVER); } public ChannelFuture connect(InetSocketAddress remote, InetSocketAddress local, ClientConfig clientConfig) { ChannelFuture future = local != null ? bootstrap.connect(remote, local) : bootstrap.connect(remote); if (future.channel() != null) future.channel().attr(CONFIG_KEY).set(clientConfig); future.addListener(f -> { if (f.isSuccess()) { future.channel().attr(CONFIG_KEY).set(clientConfig); LOGGER.info("start netty client success, remote={}, local={}", remote, local); } else { LOGGER.error("start netty client failure, remote={}, local={}", remote, local, f.cause()); } }); return future; } public ChannelFuture connect(String host, int port, ClientConfig clientConfig) { return connect(new InetSocketAddress(host, port), null, clientConfig); } public Bootstrap getBootstrap() { return bootstrap; } public NioEventLoopGroup getWorkerGroup() { return workerGroup; } }